package com.bjpowernode.web.service;

import com.bjpowernode.constants.Constant;
import com.bjpowernode.constants.RedisKey;
import com.bjpowernode.web.config.TencentSmsConfig;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author 麦翔盛
 * @ClassName: TencentSmsService
 * @Package: com.bjpowernode.web.service
 * @description: 短信接口
 * @date 2022/5/20 20:49
 */
@Service
public class SmsService {

    @Resource
    private TencentSmsConfig tencentSmsConfig;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 发送验证码
     *
     * @param phone 电话号码
     * @return 是否发送成功
     */
    public boolean sendRegisterSmsCode(String phone) throws Exception {
        boolean doHandler = false;

        //生成4位验证码
        String code = RandomStringUtils.randomNumeric(Constant.REG_CODE_LENGTH);
        System.out.println("random = " + code);

        //执行发送
        boolean isSend = executeSendSmsCore(phone, code);

        //如果发送成功就放到redis中
        if (isSend) {
            String key = RedisKey.SMS_CODE_REG + phone;
            BoundValueOperations<String, String> opts = stringRedisTemplate.boundValueOps(key);
            //放到redis缓存中 并设置缓存时间 这里设置3分钟
            opts.set(code, 3, TimeUnit.MINUTES);
            //opts.set(code);
            //验证redis是否缓存成功
            if (stringRedisTemplate.hasKey(key)) {
                doHandler = true;
            }
            System.out.println("code = " + opts.get());
        }
        return doHandler;

    }


    /**
     * 发送登录验证码
     *
     * @param phone 电话号码
     * @return 是否发送成功
     */
    public boolean sendLoginSmsCode(String phone) throws Exception {
        boolean doHandler = false;

        //生成验证码 生成六位验证码
        String code = RandomStringUtils.randomNumeric(Constant.LOG_CODE_LENGTH);

        //发送验证码(调用第三方接口)
        boolean isSend = executeSendSmsCore(phone,code);

        //将验证码保存到redis中
        if ( isSend ){
            //如果发送成功就将code保存到redis中
            String key = RedisKey.SMS_CODE_LOG + phone;
            //todo 测试完成之后 添加过期时间
            stringRedisTemplate.boundValueOps(key).set(code);

            //判断验证码是否存到了redis中
            if (stringRedisTemplate.boundValueOps(key).get() != null){
                doHandler = true;
            }
        }

       return doHandler;
    }

    /**
     * 执行发送短信请求
     *
     * @param phone 电话号码
     * @param code  验证码
     * @return 是否发送成功
     */
    public boolean executeSendSmsCore(String phone, String code) throws Exception {
        boolean flag = false;

        //创建参数
        String[] params = {code};

        //创建短信对象
        SmsSingleSender sender = new SmsSingleSender(tencentSmsConfig.getAppid(), tencentSmsConfig.getAppKey());

        //获取发送结果
        SmsSingleSenderResult result =
                sender.sendWithParam("86", phone, tencentSmsConfig.getTemplateId(), params, tencentSmsConfig.getSmsSign(), "", "");

        //验证是否发送成功
        if (result != null && Constant.SENDER_SUCCESS.equals(result.errMsg)) {
            if (result.getResponse().statusCode == Constant.SENDER_CODE_SUCCESS && result.getResponse().reason.equals(Constant.SENDER_SUCCESS)) {
                flag = true;
            }
        }

        return flag;

    }

    /**
     * 判断这个手机的注册验证码是否在有效期
     *
     * @param phone 电话号码
     * @return 是否已经发送了
     */
    public boolean checkRegCodeExists(String phone) {
        String key = RedisKey.SMS_CODE_REG + phone;
        return stringRedisTemplate.hasKey(key);
    }

    /**
     * 判断这个手机的登录验证码是否仍然在有效期
     * @param phone 登录的手机号码
     * @return 手机验证码是否仍在有效期内
     */
    public boolean checkLogCodeExists(String phone){
        String key = RedisKey.SMS_CODE_LOG + phone;
        return stringRedisTemplate.hasKey(key);

    }


    /**
     * 验证注册验证码是否正确
     *
     * @param phone 用户电话号码
     * @param code  验证码
     * @return 是否正确
     */
    public boolean checkRegCodeValid(String phone, String code) {
        boolean check = false;
        String key = RedisKey.SMS_CODE_REG + phone;

        BoundValueOperations<String, String> opts = stringRedisTemplate.boundValueOps(key);
        //从redis中取出验证码
        if (opts.get() != null && Objects.equals(opts.get(), code)) {
            check = true;
        }
        return check;
    }

    /**
     * 验证该电话号码的验证码是否正确
     * @param phone 电话号码
     * @param code 验证码
     * @return 是否正确
     */
    public boolean checkLoginCodeValid(String phone,String code){
        String key = RedisKey.SMS_CODE_LOG + phone;
        BoundValueOperations<String, String> opts = stringRedisTemplate.boundValueOps(key);
        return opts.get() != null && Objects.equals(opts.get(), code);

    }


}
